package com.initialize.common.tool.sign;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.initialize.commom.config.exception.SignException;
import com.initialize.commom.config.system.SiteConfig;
import com.initialize.common.tool.md5.MD5;
import com.initialize.common.tool.util.DateTool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Map;

/**
 * @program: star-blockchain
 * @description: sign服务层
 * @author: Mr.Jane
 * @create: 2019-09-22 23:20
 **/
@Service
public class SignService {


    /**
     * 通过map判断
     *
     * @param stringObjectMap
     * @param sign
     * @return
     * @throws Exception
     */
    public int judgingByMap(Map<String, Object> stringObjectMap, String sign) throws Exception {
        return judging(stringObjectMap, sign);

    }

    /**
     * 通过前端接受的model判断
     *
     * @param o
     * @param sign
     * @return
     * @throws Exception
     */
    public int judgingByObject(Object o, String sign) throws Exception {
        return judging(o, sign);

    }

    @Autowired
    com.initialize.common.util.redis.RedisUtil redisUtil;

    /**
     *
     * @param o
     * @param sign
     * @return
     * @throws JsonProcessingException
     * @throws SignException
     */
    private int judging(Object o, String sign) throws JsonProcessingException, SignException {
        if (SiteConfig.FLAG && sign.equals(SignConfig.TEST_SIGN)) {
            redisUtil.sSet("sign_list", sign + new Date());
            return 0;
        }
        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(o);
        if (!json.contains("timestamp")) {
            throw new SignException("noTimestamp");
        }
        Map map = JSONObject.parseObject(JSONObject.toJSONString(o), Map.class);
        String timestamp = map.get("timestamp").toString();
        long l = DateTool.doTimeStampNew(timestamp);
        if (l > 1000 * 10 || l < -1000 * 10) {
            throw new SignException("signTimeout");
        }
        //判断sign合法性
        return judgingLegitimacy(sign, json);
    }


    /**
     * 判断sign的合法性
     * 判断sign是不是前端json生成的
     *
     * @param sign
     * @param json
     * @return
     * @throws SignException
     */
    private int judgingLegitimacy(String sign, String json) throws SignException {
        if (MD5.verify(json, sign)) {
            throw new SignException("verificationFailed");
        }
        if (redisUtil.sHasKey("sign_list", sign)) {
            return 1;
        }
        redisUtil.sSet("sign_list", sign);
        return 0;
    }
}
